use vertica_rs::{Client, ConnectionConfig};
use vertica_rs::types::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
        .init();
    // Create connection configuration
    let config = ConnectionConfig::from_url("vertica://user:password@localhost:5433/database")?;
    
    // Connect to the database
    let client = Client::new(config).await?;
    
    // Check connection
    if !client.is_ready().await {
        eprintln!("Failed to connect to database");
        return Ok(());
    }
    
    println!("Connected to Vertica database successfully!");
    
    // Ping the database
    match client.ping().await {
        Ok(_) => println!("Database ping successful"),
        Err(e) => eprintln!("Database ping failed: {}", e),
    }
    
    // Example queries
    
    // 1. Simple query
    match client.query("SELECT 1 as test").await {
        Ok(result) => {
            println!("Query returned {} rows", result.len());
            for (i, row) in result.rows().iter().enumerate() {
                println!("Row {}: {:?}", i + 1, row);
            }
        }
        Err(e) => eprintln!("Query failed: {}", e),
    }
    
    // 2. Query with parameters
    match client.execute_with_params(
        "SELECT * FROM users WHERE age > ? AND status = ?",
        &[Value::Int(25), Value::String("active".to_string())]
    ).await {
        Ok(result) => {
            println!("Parameterized query returned {} rows", result);
        }
        Err(e) => eprintln!("Parameterized query failed: {}", e),
    }
    
    // 3. Execute update
    match client.execute("UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = 1").await {
        Ok(affected) => println!("Updated {} rows", affected),
        Err(e) => eprintln!("Update failed: {}", e),
    }
    
    // 4. Transaction example
    match client.transaction().await {
        Ok(mut txn) => {
            println!("Transaction started");
            
            // Execute queries within transaction
            match txn.execute("INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com')",&vec![]).await {
                Ok(_) => println!("Insert successful"),
                Err(e) => {
                    eprintln!("Insert failed: {}", e);
                    txn.rollback().await?;
                    return Ok(());
                }
            }
            
            // Commit transaction
            match txn.commit().await {
                Ok(_) => println!("Transaction committed"),
                Err(e) => eprintln!("Commit failed: {}", e),
            }
        }
        Err(e) => eprintln!("Failed to start transaction: {}", e),
    }
    
    // 5. Batch execution
    let queries = [
        "SELECT 1",
        "SELECT 2",
        "SELECT 3",
    ];
    
    match client.execute_batch(&queries).await {
        Ok(results) => {
            println!("Batch execution completed with {} results", results.len());
            for (i, result) in results.iter().enumerate() {
                println!("Query {} returned {} rows", i + 1, result.len());
            }
        }
        Err(e) => eprintln!("Batch execution failed: {}", e),
    }
    
    // Close connection
    client.close().await?;
    println!("Connection closed");
    
    Ok(())
}